//package com.thiswhyme.fsplus.sentinel.feign.instancefilter;
//
//import com.alibaba.csp.sentinel.Entry;
//import com.alibaba.csp.sentinel.context.Context;
//import com.alibaba.csp.sentinel.node.DefaultNode;
//import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
//import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
//import com.alibaba.csp.sentinel.slots.block.BlockException;
//import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
//import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
//import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
//import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.CircuitBreaker;
//import com.alibaba.csp.sentinel.spi.SpiOrder;
//import com.thiswhyme.fsplus.utils.PatternUtils;
//import org.springframework.util.CollectionUtils;
//
//import java.util.List;
//import java.util.Set;
//import java.util.stream.Collectors;
//
///**
// * @description: 自定义熔断Slot，用于替换com.alibaba.csp.sentinel.slots.block.degrade.DegradeSlot
// * @author: thiswhyme
// * @date: 2021/4/30
// */
//@SpiOrder(-1000)
//public class CustomDegradeSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
//
//    private BlockServerContext blockServerContext;
//
//    public CustomDegradeSlot(BlockServerContext blockServerContext) {
//        this.blockServerContext = blockServerContext;
//    }
//
//    @Override
//    public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count,
//                      boolean prioritized, Object... args) throws Throwable {
//        if(PatternUtils.isIpPort(resourceWrapper.getName())) {
//            //实例级别的资源，走自定义断路校验逻辑
//            checkInstanceDegrade(resourceWrapper, context, node, count);
//        } else {
//            //其他资源，走原断路校验逻辑
//            performChecking(context, resourceWrapper);
//        }
//        fireEntry(context, resourceWrapper, node, count, prioritized, args);
//    }
//
//    void performChecking(Context context, ResourceWrapper r) throws BlockException {
//        List<CircuitBreaker> circuitBreakers = DegradeRuleManager.circuitBreakers.get(r.getName());
//        if (circuitBreakers == null || circuitBreakers.isEmpty()) {
//            return;
//        }
//        for (CircuitBreaker cb : circuitBreakers) {
//            if (!cb.tryPass(context)) {
//                throw new DegradeException(cb.getRule().getLimitApp(), cb.getRule());
//            }
//        }
//    }
//
//    /**
//     * 校验实例熔断
//     * 若发生熔断，将该实例添加到“不可用实例”容器中，到达窗口期后再从容器剔除
//     * @param resource
//     * @param context
//     * @param node
//     * @param count
//     */
//    public void checkInstanceDegrade(ResourceWrapper resource, Context context, DefaultNode node, int count) {
//        Set<DegradeRule> rules = DegradeRuleManager.getRules().stream().filter(rule -> resource.getName().equals(rule.getResource())).collect(Collectors.toSet());;
//        if (CollectionUtils.isEmpty(rules)) {
//            return;
//        }
//        for (DegradeRule rule : rules) {
//            if (!rule.passCheck(context, node, count)) {
//                blockServerContext.add(resource.getName(), System.currentTimeMillis() + rule.getTimeWindow() * 1000);
//            }
//        }
//    }
//
//    @Override
//    public void exit(Context context, ResourceWrapper r, int count, Object... args) {
//        Entry curEntry = context.getCurEntry();
//        if (curEntry.getBlockError() != null) {
//            fireExit(context, r, count, args);
//            return;
//        }
//        List<CircuitBreaker> circuitBreakers = DegradeRuleManager.getCircuitBreakers(r.getName());
//        if (circuitBreakers == null || circuitBreakers.isEmpty()) {
//            fireExit(context, r, count, args);
//            return;
//        }
//
//        if (curEntry.getBlockError() == null) {
//            // passed request
//            for (CircuitBreaker circuitBreaker : circuitBreakers) {
//                circuitBreaker.onRequestComplete(context);
//            }
//        }
//
//        fireExit(context, r, count, args);
//    }
//}
